local desc_wdtx_mode = [[
  # 问鼎天下简介
  ___

  肉鸽构建卡牌与三国杀玩法相结合。以构筑卡组为核心机制玩法。该模式仅限玩家一人。烧条时间改为60s最佳。

  游戏机制：
  
    游戏开始。玩家拥有【抽】标记的私人牌堆且【问鼎天下】卡组加入此牌堆。你摸牌只能从此卡组摸牌（回合结束时会从”弃“牌堆加入“抽”牌堆洗牌）。每当从战斗外的机制（剧情，商店，宝箱等等）获得卡牌都会进入此牌堆。
    
    战斗中每当有牌进入弃牌堆，其中包含此卡组的牌则会进入玩家【弃】标记私人牌对。

  卡牌构筑：

    初始牌组为军八卡组（闪电，连弩除外），大部分卡牌（一些装备除外）可以通过模式机制升级（升级机制看卡牌说明）
  
  地图剧情：
  
    生成随机的剧情事件。包含战斗，开宝箱，商店。其他子事件。

]]
local WdtxObj = require "packages/wdtx/WdtxObj"
local Story = require "packages/wdtx/Story"
local WD = require "packages/wdtx/WdtxData"
local MobileSelGenMuty = require "packages/lang/MobileSelGenMuty"

--开启测试
local IStest
-- local IStest
--开启测试AI武将
local IStestAI = false
--玩家测试武将
local TESTgen = "mouxusheng"
--测试AI武将（避免自由选）
local TESTgens = {"guozhao","m_ex__liaohua","zhangfen","xielingyu","zhouyi","ol__tengfanglan","dongyun","l__zhangliao","ex__simayi","ol_ex__zhangjiao","ty_ex__zhuran","l__lvbu","ty__yanghu","zhaotongzhaoguang","joy__xunyou","miniex__huangyueying","ty__yanghu","joy__xunyou","godzhaoyun","js__guanyu","lvlingqi","dukui","ty_ex__wuyi","ol_ex__sunjian","xizhicai","qinmi","godganning","ty__chenlin","ex__ganning","yuejiu","caomao","ty__lidian","ol__luyusheng","godganning","ty_ex__caozhi","zhaotongzhaoguang"}
--过滤其他卡组（只允许白名单的卡组加入牌堆）
local WHILEcards = {"standard","standard_cards","maneuvering","lang_cards","tenyear_token","mobile_derived","ol_token","overseas_token"}
--保留玩家本模式重要的标记
-- local SAVEmarks = {"curlayerphase","@slash_dmg","@trick_dmg","@pdlbox","@gold_num","@df_lingxin","@shieldnum","@slash_num"}

--初始化游戏对象
local initGameObj = function(player)
  --初始化游戏数据
  local initGameData = {
    storyid = 1,
    endstoryid = 2,
    upcards = WD:getCanUpCards(),
    costcards = WD:getCostCardsData(),
    batsetmentdata = WD:getBatSetmentData(),
    boxdata = WD:getBoxData(),
    shopdata = WD:getShopData(),
    battledata = WD:getBattleData(),
    othereventdata = WD:getOtherEventData(),
    mapdata = WD:getInitMapData(),
    
    storyinfo = {
      events = {"beginAdventure"},--剧情列表  
      dialogconfig = {
        {
          {dialog = {{talkers={1,"hxfc_author",2,player.general},say="欢迎来到问鼎天下，此刻你拥有问鼎卡组（点你武将面板的”抽“可观看）。你摸牌只能从此卡组摸牌（回合结束时会从”弃“牌堆加入“抽”牌堆洗牌），进入弃牌堆中包含此卡组牌会进入你面板”弃“牌堆。此卡组牌能够升级关键时候助你一臂之力。长路漫漫，选一个奖励去冒险吧。"}},--对话内容：talkers的索引第1和第3值分别是对应剧情左右将卡位置（1为左，2为右）。索引第2和第4值分别是对应g该位置上将名。默认从索引1的将卡位置开始说话，say为说话内容
            choices = {"技能4选1","升级2张牌","获得15金币","移除3张牌","从4张牌选2张加入卡组"}, --选项，每段剧情至少有个选项，Story.ContinueStory为”继续“选项，同理Story.NextStory为”下一章“选项
            eventchc = {1,1,1,1,1}
          }, 
        },
      },
    },
    -- chcskills = {{"gongjian","ex__zhiheng","ex__jianxiong","ex__yiji","leiji","ex__fankui","yuandi","jiexing","suifu","ty__canshi","huayi","souying","pingxi","renzheng","ty__songci","ty__wenji","huace","daoshu"},
    -- {"jishan","zhenqiao","pingtao","juelie","yiyong","suchou","xinyou","fangdu","fengyan","shiyuan","qianlong","huayi","caizhuang","mansi","zhaowen","jingzao","jinjian","poyuan","ty__benyu_active"}}
  }
  player.room:addPlayerMark(player,"@gold_num",IStest and 900 or 10)
  player.room.logic.Wdtx = WdtxObj:new(player,initGameData) --注册一个问鼎天下对象
end

---@return boolean
local function execGameEvent(tp, ...)
  local event = tp:create(...)
  local _, ret = event:exec()
  return ret
end

local wdtx_getLogic = function()
  local wdtx_logic = GameLogic:subclass("wdtx_logic")

  function wdtx_logic:initialize(room)
    GameLogic.initialize(self, room)
    self.role_table = {
      { "lord" },
      { "lord", "rebel" },
      { "lord", "rebel", "rebel" },
      { "lord", "rebel", "rebel", "rebel" },
      { "lord", "rebel", "rebel", "rebel", "rebel" },
      { "lord", "loyalist", "loyalist", "loyalist", "rebel", "rebel" },
      { "lord", "rebel", "rebel", "rebel", "rebel", "rebel", "rebel" },
      { "lord", "loyalist", "loyalist", "rebel", "rebel", "rebel", "loyalist", "loyalist" },
    }
  end

  function wdtx_logic:action()
    self:trigger(fk.GamePrepared)
    local room = self.room

    while true do
      execGameEvent(GameEvent.Round)
      if room.game_finished then break end
    end
  end

  function wdtx_logic:prepareForStart()
    local room = self.room
    local players = room.players
    self:addTriggerSkill(GameRule)
    for _, trig in ipairs(Fk.global_trigger) do
      if trig.name ~= "mobile_effect" then  --关闭手杀特效
        self:addTriggerSkill(trig)
      end
    end
    self.room:sendLog{ type = "$GameStart" }
  end

  function wdtx_logic:prepareDrawPile()
    local room = self.room
    --重新过滤卡组
    local filterCardIds = {}
    local excepts = {"savage_assault","collateral","rep_crossbow","archery_attack","crossbow","lightning"} -- 删除一些卡组
    local allCardIds = Fk:getAllCardIds()
    for i = 1, #allCardIds do
      local id = allCardIds[i]
      local card = Fk:getCardById(id)
      if card then
        if card.is_derived then
          table.insert(room.void, id)
          room:setCardArea(id, Card.Void, nil)
        else
          if table.contains(WHILEcards,card.package.name) then
            if not table.contains(excepts,card.trueName) then
              table.insert(filterCardIds,id)
            end
            if WD:getInitCards()[card.name] then
              table.insert(room.void, id)
              room:setCardArea(id, Card.Void, nil)
            end
          end
        end
      end
    end
    table.shuffle(filterCardIds)
    room.draw_pile = filterCardIds
    room.totalcards = allCardIds
    for _, id in ipairs(room.draw_pile) do
      room:setCardArea(id, Card.DrawPile, nil)
    end
  end

  function wdtx_logic:assignRoles()
    local room = self.room
    local n = #room.players
    local roles = self.role_table[n]
    table.shuffle(roles)
    local bots_t = {}
    local players_t = {}
    for i = 1, n do
      local p = room.players[i]
      if p.id < 0 then
        table.insert(bots_t,{p.id,i})
      else
        table.insert(players_t,{p.id,i})
      end
    end
    local randplayer = room.players[table.random(players_t)[2]]
    randplayer.role = "lord"
    randplayer.role_shown = true
    room:broadcastProperty(randplayer, "role")

    for i = 1, n do
      local p = room.players[i]
      if p.role ~= "lord" then
        p.role = p.id < 0 and "rebel" or "loyalist"
        p.role_shown = true
        room:broadcastProperty(p,"role")
      end
    end
  end

  function wdtx_logic:chooseGenerals()
    local room = self.room
    local lord = room:getLord()
    room.current = lord
    local nonlord = room:getOtherPlayers(lord)

    MobileSelGenMuty:new({
      generalNum = 8,
      repcount = 1,
      istest = IStest,
      closeskin = true,
      jumpsysaipool = true,
      genpoolname = "MN_XLKJ",
      aipoolname = "WDTX"
    })

    initGameObj(lord)
  end
  return wdtx_logic
end

---------------------------------------技能--------------------------------------------
local wdtx_modskill = fk.CreateTriggerSkill{
  name = "#wdtx_modskill",
  frequency = Skill.Compulsory,
  mute = true,
  priority = 59,
  events = {fk.EventPhaseChanging},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and data.to == Player.Discard and table.find(player.player_cards[Player.Hand],function(id) return Fk:getCardById(id):getMark("@@staymax") ~= 0 end)
  end,
  on_use = function(self, event, target, player, data)
    return true
  end,
  refresh_events = {fk.BeforeDrawCard,fk.AfterCardsMove,fk.CardUseFinished,fk.TurnEnd},
  can_refresh = function(self, event, target, player, data)
    if not player:hasSkill(self) then return end
    if event == fk.BeforeDrawCard then 
      return player == target and player.id > 0
    end
    if event == fk.AfterCardsMove then
      for _, move in ipairs(data) do
        if move.toArea == Card.DiscardPile then
          local todiscards = {}
          for _, info in ipairs(move.moveInfo) do
            local card = Fk:getCardById(info.cardId)
            local ownerid = card:getMark("card_owner")
            if player.id == ownerid and table.contains(player.room.discard_pile, info.cardId) then
              table.insert(todiscards,info.cardId)
            end
          end
          if #todiscards > 0 then
            self.cost_data = todiscards
            return true
          end
        end
      end
      return
    end
    -- if event == fk.AfterDrawNCards then
    --   return player == target
    -- end
    if event == fk.CardUseFinished and player == target and data.card.id ~= 0 and data.card:getMark("@@costcard") ~= 0 and player.room:getCardArea(data.card) == Card.Processing then
      return true
    end
    if event == fk.TurnEnd then
      return player.room.current == target and #target:getPile("self_discs") > 0
    end
  end,
  on_refresh = function(self, event, target, player, data)
    local room = player.room
    if event == fk.BeforeDrawCard then
      local Wdtx = room.logic.Wdtx
      local num = data.num
      data.num = 0
      Wdtx:drawCards(num)
    end
    if event == fk.AfterCardsMove then
      if self.cost_data and #self.cost_data > 0 then
        -- room:delay(300)
        local Wdtx = room.logic.Wdtx
        Wdtx:checkUpTmpCards(self.cost_data)
        player:addToPile("self_discs", self.cost_data, true, self.name)
      end
      return
    end
    if event == fk.TurnEnd then
      local Wdtx = room.logic.Wdtx
      Wdtx:shuffCards()
    elseif event == fk.AfterDrawNCards then
      local draw_num = data.n
      local draw_pile = player:getPile("self_draws")
      if draw_num > #draw_pile then --摸牌阶段抽牌区不够抽
        local discs_pile = player:getPile("self_discs")
        if #draw_pile > 0 then
          room:moveCards({
            from = player.id,
            ids = draw_pile,
            fromArea = Card.PlayerSpecial,
            to = player.id,
            toArea = Card.PlayerHand,
            moveReason = fk.ReasonJustMove,
            proposer = player.id,
            skillName = self.name,
          })
        end
        if #discs_pile == 0 then return end
      else  --摸牌阶段抽牌
        local drawcards = table.random(draw_pile,draw_num)
        room:moveCards({
          from = player.id,
          ids = drawcards,
          fromArea = Card.PlayerSpecial,
          to = player.id,
          toArea = Card.PlayerHand,
          moveReason = fk.ReasonJustMove,
          proposer = player.id,
          skillName = self.name,
        })
      end
    elseif event == fk.CardUseFinished then
      player:addToPile("self_cost", {data.card.id}, true, self.name)
    end
  end,
}
Fk:addSkill(wdtx_modskill)
local wdtx_xianyu = fk.CreateTriggerSkill{
  name = "wdtx_xianyu",
  frequency = Skill.Compulsory,
  events = {fk.TurnEnd,fk.DamageInflicted},
  can_trigger = function(self, event, target, player, data)
    if not player:hasSkill(self.name) then return end
    if event == fk.TurnEnd then
      return target == player
    else
      return data.to == player and player:getMark("xy_reddamaged") > 0 and player:usedSkillTimes(self.name, Player.HistoryTurn) == 0
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.TurnEnd then
      local havedamage,haveusecard
      room.logic:getEventsOfScope(GameEvent.Damage, 3, function(e)
        for _,info in ipairs(e.data) do
          if info.from and info.from == player and info.damage > 0 then
            havedamage = true
          end
        end
      end, Player.HistoryTurn) 
      room.logic:getEventsOfScope(GameEvent.UseCard, 99, function(e)
        for _,info in ipairs(e.data) do
          if info.from and info.from == player.id and info.tos and table.find(TargetGroup:getRealTargets(info.tos),function(t) return player.id ~= t end) then
            haveusecard = true
          end
        end
      end, Player.HistoryTurn) 
      if not havedamage then
        room:setPlayerMark(player,"xy_reddamaged",1)
      else
        room:setPlayerMark(player,"xy_reddamaged",0)
      end

      if not haveusecard then
        local lingxinbyskill = player:getMark("xy_lingxin")
        if lingxinbyskill < 5 then
          room:addPlayerMark(player,"xy_lingxin",1)
          room:addPlayerMark(player,"@df_lingxin",1)
        end
      else
        local lingxinbyskill = player:getMark("xy_lingxin")
        if lingxinbyskill > 0 then
          room:removePlayerMark(player,"xy_lingxin",lingxinbyskill)
          room:removePlayerMark(player,"@df_lingxin",lingxinbyskill)
        end
      end
    else
      data.damage = data.damage - 1
    end
  end
}
local wdtx_xianyu_maxhands = fk.CreateMaxCardsSkill{
  name = "#wdtx_xianyu_maxhands",
  correct_func = function (self, player)
    if player:hasSkill(wdtx_xianyu) and player:getMark("@df_lingxin") > 0 then
      return player:getMark("@df_lingxin")
    end
  end,
}
wdtx_xianyu:addRelatedSkill(wdtx_xianyu_maxhands)
Fk:loadTranslationTable{
  ["wdtx_xianyu"] = "咸鱼",
  ["#wdtx_xianyu_maxhands"] = "咸鱼",
  ["@df_lingxin"] = "凌心",
  [":wdtx_xianyu"] = "锁定技，本回合结束，若期间没有造成伤害则每回合受到伤害-1直到下回合结束，若期间没有使用牌或使用牌指向目标只为自己则获得‘凌心’标记+1（增加手牌上限，最多+5），否则移除以此法获得的‘凌心’。",
}
Fk:addSkill(wdtx_xianyu)
---------------------------------------技能--------------------------------------------
-- local siwang = fk.CreateActiveSkill{
--   name = "wdtx_siwang",
--   -- anim_type = "offensive",
--   -- card_num = 1,
--   target_num = 1,
--   prompt = "#ty__xiongsuan",
--   can_use = function(self, player)
--     return true
--   end,
--   target_filter = function(self, to_select, selected, cards)
--     return #selected == 0 
--   end,
--   on_use = function(self, room, effect)
--     room:killPlayer({ who = effect.tos[1] }) 
--   end,
-- }
-- Fk:addSkill(siwang)

--问鼎天下模式
local wdtx_rule = fk.CreateTriggerSkill{
  name = "#wdtx_rule",
  priority = 0.001,
  refresh_events = {fk.GameStart,fk.BuryVictim,fk.GameOverJudge,fk.Deathed},
  can_refresh = function(self, event, target, player, data)
    if event ~= fk.GameStart then
      return player == target
    else
      return player.id > 0 and player.role == "lord"
    end
  end,
  on_refresh = function(self, event, target, player, data)
    local room = player.room
    if event == fk.BuryVictim then
      room:setTag("SkipGameRule", true)
      room:setTag("SkipNormalDeathProcess", true)
    elseif event == fk.Deathed then
      local Wdtx = room.logic.Wdtx
      room:setTag("SkipGameRule", true)
      if room:getTag("startwdtx") == 0 then return end
      local tar = room:getLord()
      if data.who == tar.id then
        room:gameOver("rebel")
        return
      end
      local rebelalldead = table.every(room.alive_players,function(pr) return GensLimts:isSameCamp(pr,tar) end)
      if not rebelalldead then return end
      Wdtx:defeatAllRobots()
    elseif event == fk.GameStart then
      room:setTag("startwdtx",0)
      local Wdtx = room.logic.Wdtx
      local humans = 0
      for _, pr in ipairs(room.players) do
        if pr.id < 0 then
          if pr.role == "rebel" then
            room:killPlayer({ who = pr.id }) 
          end
        else
          humans = humans + 1
        end
      end
      if humans ~= 1 then
        return room:gameOver("rebel")
      end
      room:setTag("startwdtx",1)
      Wdtx:addInitCardsToArea(table.clone(WD:getInitCards()))
      room:handleAddLoseSkills(player, "#wdtx_modskill", nil, false)
      if IStest then
        room:handleAddLoseSkills(player, "damage_maker|cheat|rende|wdtx_xianyu", nil, false)--|damage_maker|cheat|rende
      end
      -- player:throwAllCards("h")
      for _, trig in ipairs(Fk.global_trigger) do
        if trig.name == "mobile_effect" then  --开手杀特效
          room.logic:addTriggerSkill(trig)
        end
      end
      Wdtx:nextStory()
    elseif event == fk.GameOverJudge then
      room:setTag("SkipGameRule", true)
      local room = player.room
      if room:getTag("startwdtx") == 0 then return end

      local Wdtx = room.logic.Wdtx
      local status = Wdtx:getStoryStatus()        
      if data.who < 0 then
        local tar = room:getPlayerById(data.who)
        if not Wdtx:curPlayerisTriEvent(tar.general) then
          Wdtx:changeSoldier(tar)
        end
      else
        -- if status ~= Story.StatusDeath then
        --   Wdtx:handleStoryStatus()
        -- end
      end      
    end
  end,
}
Fk:addSkill(wdtx_rule)

local wdtx_mode = fk.CreateGameMode{
  name = "wdtx_mode",
  minPlayer = 5,
  maxPlayer = 5,
  rule = wdtx_rule,
  logic = wdtx_getLogic,
  whitelist = table.clone(WHILEcards),
  winner_getter = function(self, victim)
    local room = victim.room
    local alive = table.filter(room.alive_players, function(p)
      return not p.surrendered
    end)
    if #alive ~= 1 then return "" end
    return alive[1].role
  end,
  surrender_func = function(self, playedTime)
    local surrenderJudge = { { text = "time limitation: 10s", passed = playedTime >= 10 } }
    -- if Self.role ~= "lord" then
      table.insert(surrenderJudge, { text = "1v1: left you alive", passed = true})
    -- end
    return surrenderJudge
  end,
}

Fk:loadTranslationTable{
  ["hxfc_author"] = "幻想风车",
  ["author_says"] = "前言",
  ["wdtx_mode"] = "问鼎天下",
  ["#wdtx_rule"] = "问鼎天下",
  ["#wdtx_modskill"] = "",
  ["@gold_num"] = "币:",
  -- [":wdtx_modskill"] = "你摸牌只从“抽卡区”摸牌，进入弃牌堆中的牌包含有你“抽卡区”的牌则进入你的“弃卡区”",
  ["self_draws"] = "抽:",
  ["self_discs"] = "弃:",
  ["self_cost"] = "墓:",
  ["selgold"] = "拿%arg币",
  ["rec_hp"] = "回复%arg体力",

  ["shop"] = "商店",
  ["Exist"] = "离开",
  ["entershop"] = "进入商店",
  ["buyskills"] = "购买技能",
  ["buycards"] = "购买卡牌",
  ["uplvcards"] = "升1张牌(需%arg币)",
  ["forgetcards"] = "丢1张牌(需%arg币)",

  ["map_select"] = "地图选择",

  -- ["randomskill_4_1"] = "初入乱世",
  ["wdtx_rewardchc"] = "选择两项奖励",

  ["meetHuangJin"] = "路遇黄巾",
  ["saveGuanZhang"] = "关张奋战",
  
  ["recoverall"] = "治愈",
  [":recoverall"] = "恢复全部体力",

  -- ["self_draws"] = "抽卡区",
  -- ["self_discs"] = "弃卡区",
  -- ["emy_atk_cards"] = "进攻意图",

  ["@up_damage"] = "伤害+",
  ["@up_strongmark"] = "重伤+",
  ["@up_weakmark"] = "虚弱+",
  ["@up_defmark"] = "护甲+",
  ["@up_shdmgmark"] = "盾杀+",
  ["@up_likeslashmark"] = "杀牌-",
  ["@sub_cost"] = "费-",
  ["@up_drawmark"] = "抽卡+",
  ["@up_atknum"] = "次数+",
  ["@@up_equipall"] = "升级手牌",
  ["@up_power"] = "力量+",

  ["beginAdventure"] = "问鼎天下",
  -- ["againOnce"] = "再来一次",
  ["normonster"] = "普通怪",
  ["elitemonster"] = "精英怪",
  ["box"] = "宝箱",
  ["boss"] = "BOSS",
  ["rest"] = "休息",
  ["otherevents"] = "？？",

  [":wdtx_mode"] = desc_wdtx_mode,
}

return wdtx_mode
